package com.zg.common.web.aop;

import java.io.FileNotFoundException;
import java.io.IOException;

import com.zg.common.core.R;
import com.zg.common.core.exception.BusinessException;
import com.zg.common.core.exception.E;
import com.zg.common.core.exception.SystemException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolationException;

/**
 * 全局异常拦截
 * @author Zxb
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(BusinessException.class)
    public R<?> exception(BusinessException e) {
        log.warn("业务异常", e);
        return R.error(e.getCode(), e.getMsg());
    }

    @ResponseBody
    @ExceptionHandler(SystemException.class)
    public R<?> exception(SystemException e) {
        log.error("系统异常", e);
        return R.error(e.getCode(), e.getMsg());
    }

    @ResponseBody
    @ExceptionHandler(FileNotFoundException.class)
    public R<?> exception(FileNotFoundException e) {
        log.error("文件未找到异常", e);
        return R.error(E.FILE_NOT_FIND);
    }

    @ResponseBody
    @ExceptionHandler(IOException.class)
    public R<?> exception(IOException e) {
        log.error("IO异常", e);
        return R.error(E.IO_ERROR);
    }

    @ResponseBody
    @ExceptionHandler(BindException.class)
    public R<?> exception(BindException e) {
        FieldError fe = e.getFieldError();
        String msg = null;
        if (fe != null) {
            msg = fe.getDefaultMessage();
        }
        log.error("参数绑定异常", e);
        return R.error(msg);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public R<?> exception(ConstraintViolationException e) {
        log.error("参数校验异常", e);
        return R.error(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(ClassNotFoundException.class)
    public R<?> exception(ClassNotFoundException e) {
        log.error("类未找到异常", e);
        return R.error(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public R<?> exception(Exception e) {
        log.error("其他异常", e);
        return R.error(500, "操作过程出现异常：" + e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<?> exception(HttpRequestMethodNotSupportedException e) {
        log.error("请求方法错误异常", e);
        return R.error(E.BAD_METHOD);
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public R<?> exception(MethodArgumentTypeMismatchException e) {
        log.error("请求参数类型不匹配异常", e);
        return R.error(E.BAD_PARAM.getMsg() + "【" + e.getParameter().getParameterName() + "】");
    }
}
